<script setup lang="ts">
import * as ConfigApi from '@/api/infra/config'
import { ThemeApi, ThemeGrid, ThemeVO } from '@/api/pb/theme'
import { FormInstance, FormRules } from 'element-plus'
import { CSSProperties } from 'vue'
import { useEmitt } from '@/hooks/web/useEmitt'
import {InitialThemeIdConfigKey} from "@/types/web3d";

const router = useRouter()
const message = useMessage()

const loading = inject<Ref<boolean>>('loading')!

// 网格数据
const themeList = inject<Ref<ThemeVO[]>>('themeList')!

// 列与行数
const layoutColSize = inject<Ref<number>>('layoutColSize')!
const layoutRowSize = inject<Ref<number>>('layoutRowSize')!

// 获取数据方法
const getList = inject<Function>('getList')!

// 表单数据
const formRef = ref<FormInstance>()
const formData = ref<Partial<ThemeVO>>({
  name: undefined,
  introduce: undefined,
  grid: {
    label: '新主题',
    css: {}
  } as ThemeGrid
})
const formRules = ref<FormRules<ThemeVO>>({
  name: [{ required: true, message: '请输入主题名称', trigger: 'blur' }],
  introduce: [{ required: true, message: '请输入主题介绍', trigger: 'blur' }]
})
// 预设颜色
const predefineColors = ref([
  '#000000',
  '#EEEEEE',
  '#ff4500',
  '#ff8c00',
  '#ffd700',
  '#90ee90',
  '#00ced1',
  '#1e90ff',
  '#c71585',
  'rgba(255, 69, 0, 0.68)',
  'rgb(255, 120, 0)',
  'hsl(181, 100%, 37%)',
  'hsla(209, 100%, 56%, 0.73)',
  '#c7158577'
])
// 网格高亮预设
const setBoxShadow = (theme: ThemeVO) => {
  const color = theme.grid.css!.backgroundColor || '#666666'
  theme.grid.css!.boxShadow = `0px 0px 40px ${color}`
}

/**
 * 编辑主题
 */
// 编辑模式
const isEdit = ref(false)
// 编辑主题对象
const editThemeObject = ref<ThemeVO | null>(null)

// 添加
const addTheme = () => {
  isEdit.value = true

  const w = 2
  const h = 2
  editThemeObject.value = {
    name: '新主题',
    grid: {
      x: 0,
      y: 0,
      w: w,
      h: h,
      static: false,
      label: '新主题',
      i: '新主题',
      css: {
        backgroundColor: '#FACC15',
        color: '#000000'
      }
    }
  } as ThemeVO
  formData.value = editThemeObject.value
  themeList.value.push(editThemeObject.value)
}

// 修改
const oldThemeList = ref<ThemeVO[] | null>(null)
const updateTheme = (theme: ThemeVO) => {
  if (isEdit.value) {
    if(theme !== editThemeObject.value){
      message.info('请先保存当前主题')
    }
    return
  }

  oldThemeList.value = JSON.parse(JSON.stringify(themeList.value))

  isEdit.value = true

  editThemeObject.value = theme
  editThemeObject.value.grid.static = false

  formData.value = editThemeObject.value
}

// 取消
const cancelEdit = () => {
  if (!editThemeObject.value!.id) {
    themeList.value.forEach((item, index) => {
      if (item === editThemeObject.value) {
        themeList.value.splice(index, 1)
      }
    })
  }

  isEdit.value = false
  if (oldThemeList.value) {
    themeList.value = oldThemeList.value
    oldThemeList.value = null
  }
  resetTheme()
}

// 保存
const saveTheme = async () => {
  for (const item of themeList.value) {
    const grid = item.grid
    const xEnd = grid.x + grid.w
    const yEnd = grid.y + grid.h
    if (xEnd > layoutColSize.value || yEnd > layoutRowSize.value) {
      message.alertWarning('部分主题超出网格限制，请检查')
      return
    }
  }

  const valid = await formRef.value!.validate()
  if (!valid) return

  loading.value = true

  const data = { ...editThemeObject.value!, ...formData.value } as ThemeVO
  if (data.id) {
    await ThemeApi.updateTheme(data)
  } else {
    data.grid.i = ''
    await ThemeApi.createTheme(data)
  }
  message.success('保存成功')
  await getList()

  isEdit.value = false

  resetTheme()

  loading.value = false
}

// 重置当前编辑主题数据
const resetTheme = () => {
  editThemeObject.value!.grid.static = true
  editThemeObject.value = null

  formData.value = {
    name: undefined,
    introduce: undefined,
    grid: {
      label: '新主题',
      css: {}
    } as ThemeGrid
  }
}

/**
 * 高亮显示网格
 */
// 鼠标移入时高亮显示
const highlightThemeMoveOver = (id: number) => {
  if (isEdit.value) return

  for (const theme of themeList.value) {
    if (theme.grid.i === id) {
      if (!theme.grid.css) theme.grid.css = {} as CSSProperties
      setBoxShadow(theme)
      return
    }
  }
}

// 鼠标移出时取消高亮
const highlightThemeMoveOut = (id: number) => {
  if (isEdit.value) return

  for (const theme of themeList.value) {
    if (theme.grid.i === id) {
      if (!theme.grid.css) theme.grid.css = {} as CSSProperties
      theme.grid.css!.boxShadow = ''
      return
    }
  }
}

/** 前往修改模型 */
const toUpdateModel = (id: number) => {
  router.push({name: 'Web3dModel', params: {id}})
}

/** 设置初始房间 */
const initialThemeId = inject<Ref<string | null>>('initialThemeId')!
const setInitialTheme = async () => {
  const id = editThemeObject.value!.id
  await ConfigApi.updateConfigValueByKey(InitialThemeIdConfigKey, id.toString())
  initialThemeId.value = id.toString()
  message.success('设置成功')
}

/** 删除主题 */
const deleteTheme = async () => {
  try {
    await message.delConfirm()

    loading.value = true

    const id = editThemeObject.value!.id
    await ThemeApi.deleteTheme(id)
    message.success('删除成功')
    cancelEdit()

    await getList()

  } finally {
    loading.value = false
  }
}

const init = () => {
  useEmitt({name: 'updateTheme', callback: updateTheme})
  useEmitt({name: 'highlightThemeMoveOver', callback: highlightThemeMoveOver})
  useEmitt({name: 'highlightThemeMoveOut', callback: highlightThemeMoveOut})
}
init()

</script>

<template>
  <div class="w-full flex justify-center">
    <Transition>
      <div class="w-full text-center" v-if="!isEdit">
        <div class="text-left font-bold mb-4 ml-4 text-xl">主题列表</div>
        <el-scrollbar>
          <el-card
            class="theme-list w-60 mx-a mb-2 cursor-pointer"
            v-for="(item, index) in themeList"
            :key="item.id"
            @click="updateTheme(item)"
            @mouseenter="highlightThemeMoveOver(item.id)"
            @mouseleave="highlightThemeMoveOut(item.id)"
          >
            <el-tag
              class="mb-2"
              v-if="initialThemeId ? item.id == Number(initialThemeId) : index === 0"
              type="primary"
            >
              初始房间
            </el-tag>
            <div class="px-2">
              <div class="font-bold text-xl">
                {{ item.name }}
              </div>
              <div v-if="item.remark" class="text-gray text-sm mt-2">
                {{ item.remark }}
              </div>
            </div>
          </el-card>
        </el-scrollbar>
        <el-button type="primary" size="large" @click="addTheme"> 添加新主题 </el-button>
      </div>
    </Transition>

    <Transition>
      <div v-if="isEdit" class="text-center">
        <el-card class="edit-mode-card mb-4">
          <div class="font-bold text-xl"> 编辑模式 </div>
        </el-card>
        <el-button class="mb-4" type="primary" @click="setInitialTheme">设置为初始房间</el-button>
        <el-form class="mb-4" ref="formRef" :model="formData" :rules="formRules">
          <el-form-item label="主题名称" prop="name" required>
            <el-input v-model="formData.name" placeholder="请输入主题名称" />
          </el-form-item>
          <el-form-item label="主题介绍" prop="introduce" required>
            <el-input
              v-model="formData.introduce"
              type="textarea"
              placeholder="请输入主题介绍"
              resize="none"
              :autosize="{ minRows: 3, maxRows: 18 }"
              maxlength="256"
            />
          </el-form-item>
          <el-form-item label="备注" prop="remark">
            <el-input v-model="formData.remark" placeholder="请输入备注" />
          </el-form-item>
          <el-form-item label="网格展示"><div></div></el-form-item>
          <el-form-item label="展示标签" prop="grid.label">
            <el-input v-model="formData.grid!.label" placeholder="请输入主题名称" />
          </el-form-item>
          <el-form-item label="标签背景颜色" prop="grid.css.backgroundColor">
            <el-color-picker
              v-model="formData.grid!.css.backgroundColor"
              :predefine="predefineColors"
            />
          </el-form-item>
          <el-form-item label="标签字体颜色" prop="grid.css.color">
            <el-color-picker v-model="formData.grid!.css.color" :predefine="predefineColors" />
          </el-form-item>
          <!--        <el-form-item label="标签字体大小" prop="grid.css.fontSize">-->
          <!--          <el-input-number-->
          <!--            v-model="formData.grid!.css.fontSize"-->
          <!--            :min="1"-->
          <!--            :max="32"-->
          <!--          />-->
          <!--        </el-form-item>-->

          <el-form-item v-if="formData.id" label="模型相关"><div></div></el-form-item>
          <el-form-item v-if="formData.id" label="模型修改">
            <el-button type="primary" @click="toUpdateModel(formData.id)">前往修改</el-button>
          </el-form-item>
        </el-form>


        <div class="mt-16">
          <el-button type="warning" @click="cancelEdit">取消修改</el-button>
          <el-button type="primary" @click="saveTheme">保存修改</el-button>
        </div>
        <el-button class="mt-2" type="danger" @click="deleteTheme">删除主题</el-button>
      </div>
    </Transition>

  </div>
</template>

<style scoped lang="scss">
.theme-list :deep(.el-card__body) {
  height: 100%;
  padding: 8px;
  text-align: left;
}

.edit-mode-card :deep(.el-card__body) {
  padding: 8px;
}
</style>
